home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- Smaller Installer © 1993 Bill Goodman, All Rights Reserved
- *******************************************************************************
-
- Personalize Hook Example
-
- This installer hook procedure prompts the user to enter a name and organization
- string which is used to personalize the installed application. These strings
- are stored in an STR# resource (ID 1000) in the installed application. The user
- name is string #1 and the organization name is string #2. The strings are also
- saved in an "info" file on the installer startup disk so that subsequent
- installations will use the same personalization info.
-
- To use this hook procedure, you must compile this code and create a code
- resource with type 'SICR' and an ID of 500. This resource should be
- non-preloaded, nonpurgeable, unlocked, unprotected and non-sysheap. Copy this
- resource to your installer's resource file.
-
- Set the STR# resource in the "PersonalizeHook.Misc.rsrc" file to specify the
- full path to the application being installed. Change all references to "XXXX"
- in the DITL resources to use your application's name. Add all the resources in
- "PersonalizeHook.Misc.rsrc" to your installer's resource file.
-
- Copy the "Volume Info" file to the distribution disk containing the installer.
- This file must contain 512 bytes of data (preferably random in appearance).
- The first byte must be 0xFF. This file may be invisible if desired.
-
- Add an STR#[1000] resource to your application. The hook will modify the values
- in this resource after the application is installed. Add whatever code is
- appropriate to display these personalization strings in your application.
-
- ******************************************************************************/
-
- #include <SetUpA4.h>
- #include <GestaltEqu.h>
- #include "SIHookProc.h"
-
-
- /******************************************************************************
- Module Internal Function Prototypes
- ******************************************************************************/
- void SetTargetVolFunction(void);
- void EndInstallFunction(void);
-
-
- /******************************************************************************
- Constant Declarations
- ******************************************************************************/
- /* Dialog Definitions */
- #define nameDlg 500 /* Name and organization entry dialog */
- #define ok_nameDlg 1 /* OK button */
- #define name_nameDlg 3 /* Name edit text item */
- #define org_nameDlg 4 /* Organization edit text item */
-
- /* Alert Definitions */
- #define damagedAlrt 501 /* "The installer disk is damaged. Please be sure you are using the original installer disk." */
- #define nameErrAlrt 502 /* "Please enter your name AND your organization's name." */
- #define lockedAlrt 503 /* "The installer disk is locked. Please unlock it and try again." */
- #define installAlrt 504 /* "An error occurred while installing the “XXXX” application. Please remove all files in the “XXXX” folder and try again." */
-
- /* Indexed String Definitions */
- #define filePathID 500 /* File path string */
- #define personalizeID 1000 /* Personalization resource */
-
-
- /******************************************************************************
- Module Variables Declarations
- ******************************************************************************/
- SIHookParmBlk *parms; /* Global pointer to parameter block */
- Boolean firstCallDone = false; /* Set after first hook proc call */
- Str31 infoFilename = "\pVolume Info"; /* Name of info file */
- Str255 userName; /* User name string */
- Str255 userOrg; /* User organization string */
-
-
- /*****************************************************************************/
- pascal void main(
- SIHookParmBlk *parmBlk /* Pointer to parameter block */
- )
- /******************************************************************************
- This is the main entry point for the installer hook procedure.
- ******************************************************************************/
- {
- RememberA0(); /* This is necessary to access any global variables */
- SetUpA4();
- parms = parmBlk;
-
- switch (parms->function)
- {
- case siHookSetTargetVol:
- SetTargetVolFunction();
- break;
-
- case siHookEndInstall:
- EndInstallFunction();
- break;
- }
- RestoreA4();
- }
-
-
- /*****************************************************************************/
- void SetTargetVolFunction(void)
- /******************************************************************************
- Input parameters:
- "targetVRefNum" - Volume reference number of target volume
- "groupAPFlags", "groupQUSel", "groupVZSel" - Groups currently selected
- for installation
- Returns:
- "groupAPFlags", "groupQUSel", "groupVZSel" - New installation groups
-
- This function is called at startup and whenever the target volume is
- changed.
-
- NOTE: This code calls ExitToShell to terminate installer execution. This is
- acceptable for terminating execution on the first SetTargetVol call;
- however, it should not be used to terminate execution during other
- SetTargetVol calls.
- ******************************************************************************/
- {
- OSErr error;
- short infoPathNum;
- long rwCnt;
- short index;
- DialogPtr dlgPtr;
- short item;
- short tmpType;
- Handle tmpHdl;
- Rect tmpRect;
-
- if (firstCallDone)
- return; /* Execute this code only for the first SetTargetVol function call */
- firstCallDone = true;
-
- /* Open the info file */
- error = HOpen(-SFSaveDisk, fsRtDirID, infoFilename, fsCurPerm, &infoPathNum);
- if (error != noErr)
- goto DamagedError_Closed;
-
- /* Read the user name string */
- rwCnt = 256;
- error = FSRead(infoPathNum, &rwCnt, userName);
- if (error != noErr)
- goto DamagedError;
-
- /* Read the user organization string */
- rwCnt = 256;
- error = FSRead(infoPathNum, &rwCnt, userOrg);
- if (error != noErr)
- goto DamagedError;
-
- if (userName[0] == 0xFF)
- { /* Personalization strings have not been specified - prompt user to enter */
- dlgPtr = GetNewDialog(nameDlg, NULL, (WindowPtr) -1L);
- if (dlgPtr == NULL)
- goto FatalError;
- for (;;)
- {
- ModalDialog(NULL, &item);
- if (item != ok_nameDlg)
- goto CleanupAndTerminate; /* User cancelled dialog */
-
- /* Read strings from dialog */
- GetDItem(dlgPtr, name_nameDlg, &tmpType, &tmpHdl, &tmpRect);
- GetIText(tmpHdl, userName);
- GetDItem(dlgPtr, org_nameDlg, &tmpType, &tmpHdl, &tmpRect);
- GetIText(tmpHdl, userOrg);
-
- /* Validate strings */
- if ((userName[0] != 0) && (userOrg[0] != 0))
- break;
-
- CautionAlert(nameErrAlrt, NULL); /* "Entries are invalid" */
- }
- DisposDialog(dlgPtr);
-
- /* Complement the characters in the name and organization strings to disguise them */
- for (index = 256; --index >= 0;)
- userName[index] = ~userName[index];
-
- for (index = 256; --index >= 0;)
- userOrg[index] = ~userOrg[index];
-
- /* Save the strings in the info file */
- error = SetFPos(infoPathNum, fsFromStart, 0);
- if (error != noErr)
- goto FatalError;
-
- rwCnt = 256;
- error = FSWrite(infoPathNum, &rwCnt, userName);
- if (error != noErr)
- goto WriteError;
-
- rwCnt = 256;
- error = FSWrite(infoPathNum, &rwCnt, userOrg);
- if (error != noErr)
- goto WriteError;
- }
-
- /* Complement the characters in the name and organization strings to */
- /* return the strings to normal format */
- for (index = 256; --index >= 0;)
- userName[index] = ~userName[index];
-
- for (index = 256; --index >= 0;)
- userOrg[index] = ~userOrg[index];
-
- error = FSClose(infoPathNum);
- if (error != noErr)
- goto WriteError;
- return; /* Good completion */
-
- /*** Error exits ***/
-
- /* Error occured while accessing the info file */
- DamagedError:
- FSClose(infoPathNum);
-
- DamagedError_Closed:
- StopAlert(damagedAlrt, NULL); /* "Disk is damaged" */
- ExitToShell();
-
- /* Error occurred while writing the info file */
- WriteError:
- if ((error == vLckdErr) || (error == wPrErr))
- { /* Volume is locked */
- StopAlert(lockedAlrt, NULL); /* "Volume is locked" */
- goto CleanupAndTerminate;
- }
- goto DamagedError;
-
- /* Fatal error occurred */
- FatalError:
- SysBeep(1);
-
- /* Cleanup and terminate */
- CleanupAndTerminate:
- FSClose(infoPathNum);
- ExitToShell();
- }
-
-
- /*****************************************************************************/
- void EndInstallFunction(void)
- /******************************************************************************
- Input parameters:
- "targetVRefNum" - Volume reference number of target volume
- "groupAPFlags", "groupQUSel", "groupVZSel" - Groups currently selected
- for installation
- "completionSts" - Indicates any errors which occurred during installation
- Returns:
- "result" - Hook result code
-
- This function is called at the end of the installation process.
- ******************************************************************************/
- {
- Str255 filePath;
- short applResFileNum = -1;
- Handle resHdl;
- long resSize;
- unsigned char buf[514];
-
- if (parms->completionSts != siHookComplete)
- return; /* Do not try to install resource if all files weren't installed */
-
- /* Build the personalization resource */
- buf[0] = 0;
- buf[1] = 2;
- BlockMove(userName, &buf[2], (short) userName[0] + 1);
- BlockMove(userOrg, &buf[(short) userName[0] + 3], (short) userOrg[0] + 1);
-
- /* Open the installed application file */
- GetIndString(filePath, filePathID, 1);
- if (filePath[0] == 0)
- goto Fail;
- SetResLoad(false); /* Prevent loading of resources with preload attribute */
- applResFileNum = HOpenResFile(parms->targetVRefNum, 0, filePath, fsRdWrPerm);
- SetResLoad(true);
- if (applResFileNum == -1)
- goto Fail;
-
- /* Update the personalization resource in the installed application file */
- resHdl = Get1Resource('STR#', personalizeID);
- if (resHdl == 0)
- goto Fail;
- resSize = (long) userName[0] + (long) userOrg[0] + 4;
- ReallocHandle(resHdl, resSize);
- if (MemError() != noErr)
- goto Fail;
- BlockMove(buf, *resHdl, resSize);
- ChangedResource(resHdl);
- if (ResError() != noErr)
- goto Fail;
- WriteResource(resHdl);
- if (ResError() != noErr)
- goto Fail;
- CloseResFile(applResFileNum);
- if (ResError() != noErr)
- goto Fail;
- return; /* Note that it is not necessary to set the result if no error */
-
- /* Error occurred during update */
- Fail:
- parms->result = siHookAbort;
-
- if (applResFileNum != -1)
- CloseResFile(applResFileNum);
- StopAlert(installAlrt, NULL);
- }
-